1 module about_delegates;
2 
3 import dunit;
4 import helpers;
5 
6 class AboutDelegates {
7   mixin UnitTest;
8 
9 // Delegates are function pointers with context information attached.
10  int delegate(int) call_me_later;   // a delegate which takes an int and returns an int
11 
12   class Foo {
13     private int y;
14     
15     //constructor
16     this(int value) {
17      y=value;
18     }
19 
20     int mymethod(int x) {
21       return x+y;
22     }
23   }
24 
25   @Test
26   public void explicit_delegate() {
27   Foo foo = new Foo(3);
28   call_me_later = &foo.mymethod;
29   auto result=call_me_later(5);      // call mymethod(5)
30   assertEquals(result, FILL_IN_THIS_NUMBER);
31   }
32 
33   // --------------------------------------------------------------------------------
34   // delegates are useful as "event receivers". Let's define a simple GUI-like class
35 
36   alias ClickHandler=void delegate(Button);
37 
38   class Button {
39 
40     private ClickHandler[] handlers;
41 
42     private int click_counter;  //some button properties
43     private string name="UNTITLED";
44     private string color="DEFAULT";
45 
46     void click() {  // executes user defined callbacks
47                     // giving each callback full access to this "Button" context
48       foreach(h; handlers) {
49         h(this);
50       }
51       click_counter++;
52     }
53     void registerHandler(ClickHandler func)
54     {
55       handlers~=func;
56     }
57 
58     @property string state() {
59      import std.format : format;
60      return format("you clicked %d times the button %s with color %s",click_counter,name,color);
61     }
62 
63   }
64 
65   // now the class user can "attach" event handlers to instances of the class
66   // in order to change class default behavior
67 
68   @Test
69   public void delegates_for_callback() {
70     auto b1=new Button();
71     auto b2=new Button();
72     b1.registerHandler( delegate(Button b){b.name="OK";} );
73     b2.registerHandler( delegate(Button b){b.color="RED";} );
74     b2.registerHandler( delegate(Button b){b.click_counter--;} );   // can be chained
75     b1.click();
76     b1.click();
77     b2.click();
78     b2.click();
79     assertEquals(b1.state,FILL_IN_THIS_STRING);
80     assertEquals(b2.state,FILL_IN_THIS_STRING);
81   }
82 
83 
84 }